package org.example.yongyou;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;

import java.io.*;
import java.util.ArrayList;
import java.util.HashSet;

public class 用友bip建表工具 {

    public static void main(String[] args) throws IOException {

// 使用ClassLoader来获取资源文件  yongyoubipjson.txt的位置是 src/main/resources/yongyoubipjson.txt
        InputStream inputStream = 用友bip建表工具.class.getClassLoader().getResourceAsStream("yongyoubipjson.txt");
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuffer s = new StringBuffer();

        while (true) {
            String line = bufferedReader.readLine();
            if (line == null) {
                break;
            }
            s.append(line);
        }

        JSONObject jsonObject = new JSONObject(s);
        JSONArray jsonArray = (JSONArray) jsonObject.get("children");

        //1.先看一下一共有  几种类型
//        checkHowManyType(jsonArray);//[number, boolean, string, double, long, characteristic, int, BigDecimal, object]

        //2.根据这些类型，看一下怎么匹配到数据库的字段
//        HashMap<String, String> type_dbType = new HashMap<>();
//        type_dbType.put("number", "varchar(255)");
//        type_dbType.put("boolean", "varchar(255)");
//        type_dbType.put("string", "varchar(255)");
//        type_dbType.put("double", "double");
//        type_dbType.put("long", "bigint");
//        type_dbType.put("int", "int");
//        type_dbType.put("BigDecimal", "varchar(255)");

        //如果是 characteristic类型，那么不处理，不要这个字段 如果是 object类型，那么需要特殊处理一下
        ArrayList<EnName_Type_Comment> enNameTypeCommentArrayList = new ArrayList<>();
        for (Object o : jsonArray) {
            JSONObject jsonObject1 = (JSONObject) o;
            String paramType = (String) jsonObject1.get("paramType");

            if ("characteristic".equals(paramType)) {
                System.out.println("最外层的characteristic类型不处理" + jsonObject1.get("name"));
                continue;
            }
            //        type_dbType.put("number", "varchar(255)");
            if ("number".equals(paramType)) {
                enNameTypeCommentArrayList.add(new EnName_Type_Comment(jsonObject1.get("name").toString(), "varchar(255)", (String) jsonObject1.get("paramDesc")));
                continue;
            }
//        type_dbType.put("boolean", "varchar(255)");
            if ("boolean".equals(paramType)) {
                enNameTypeCommentArrayList.add(new EnName_Type_Comment(jsonObject1.get("name").toString(), "varchar(255)", (String) jsonObject1.get("paramDesc")));
                continue;
            }
//        type_dbType.put("DateTime", "varchar(255)");
            if ("DateTime".equals(paramType)) {
                enNameTypeCommentArrayList.add(new EnName_Type_Comment(jsonObject1.get("name").toString(), "varchar(255)", (String) jsonObject1.get("paramDesc")));
                continue;
            }
//        type_dbType.put("string", "varchar(255)");
            if ("string".equals(paramType)) {
                enNameTypeCommentArrayList.add(new EnName_Type_Comment(jsonObject1.get("name").toString(), "varchar(255)", (String) jsonObject1.get("paramDesc")));
                continue;
            }
//        type_dbType.put("double", "double");
            if ("double".equals(paramType)) {
                enNameTypeCommentArrayList.add(new EnName_Type_Comment(jsonObject1.get("name").toString(), "double", (String) jsonObject1.get("paramDesc")));
                continue;
            }
//        type_dbType.put("long", "bigint");
            if ("long".equals(paramType)) {
                enNameTypeCommentArrayList.add(new EnName_Type_Comment(jsonObject1.get("name").toString(), "bigint", (String) jsonObject1.get("paramDesc")));
                continue;
            }
//        type_dbType.put("int", "int");
            if ("int".equals(paramType) || "short".equals(paramType)) {
                enNameTypeCommentArrayList.add(new EnName_Type_Comment(jsonObject1.get("name").toString(), "int", (String) jsonObject1.get("paramDesc")));
                continue;
            }
//        type_dbType.put("BigDecimal", "varchar(255)");
            if ("BigDecimal".equals(paramType)) {
                enNameTypeCommentArrayList.add(new EnName_Type_Comment(jsonObject1.get("name").toString(), "varchar(255)", (String) jsonObject1.get("paramDesc")));
                continue;
            }
            if ("object".equals(paramType)) {
                String parentName = (String) jsonObject1.get("name");
                String parentParamDesc = (String) jsonObject1.get("paramDesc");
                JSONArray children = (JSONArray) jsonObject1.get("children");
                for (Object o1 : children) {
                    JSONObject jsonObject2 = (JSONObject) o1;
                    String name = (String) jsonObject2.get("name");
                    String paramDesc = (String) jsonObject2.get("paramDesc");
                    String type = (String) jsonObject2.get("paramType");
                    if ("characteristic".equals(type)) {
//                        log.warn("object_characteristic类型不处理+{}", jsonObject2.get("name"));
                        System.out.println("内层的_characteristic类型不处理" + jsonObject2.get("name"));
                        continue;
                    }
                    if ("object".equals(type)) {
//                        log.warn("object_object类型不处理+{}", jsonObject2.get("name"));
                        System.out.println("内层的_object类型不处理" + jsonObject2.get("name"));
                        continue;
                    }
                    if ("number".equals(type)) {
                        enNameTypeCommentArrayList.add(new EnName_Type_Comment(parentName + "_" + name, "varchar(255)", parentParamDesc + "-" + paramDesc));
                        continue;
                    }
                    if ("DateTime".equals(type)) {
                        enNameTypeCommentArrayList.add(new EnName_Type_Comment(parentName + "_" + name, "varchar(255)", parentParamDesc + "-" + paramDesc));
                        continue;
                    }
                    if ("boolean".equals(type)) {
                        enNameTypeCommentArrayList.add(new EnName_Type_Comment(parentName + "_" + name, "varchar(255)", parentParamDesc + "-" + paramDesc));
                        continue;
                    }
                    if ("string".equals(type)) {
                        enNameTypeCommentArrayList.add(new EnName_Type_Comment(parentName + "_" + name, "varchar(255)", parentParamDesc + "-" + paramDesc));
                        continue;
                    }
                    if ("double".equals(type)) {
                        enNameTypeCommentArrayList.add(new EnName_Type_Comment(parentName + "_" + name, "double", parentParamDesc + "-" + paramDesc));
                        continue;
                    }
                    if ("long".equals(type)) {
                        enNameTypeCommentArrayList.add(new EnName_Type_Comment(parentName + "_" + name, "bigint", parentParamDesc + "-" + paramDesc));
                        continue;
                    }
                    if ("int".equals(type) || "short".equals(type)) {
                        enNameTypeCommentArrayList.add(new EnName_Type_Comment(parentName + "_" + name, "int", parentParamDesc + "-" + paramDesc));
                        continue;
                    }
                    if ("BigDecimal".equals(type)) {
                        enNameTypeCommentArrayList.add(new EnName_Type_Comment(parentName + "_" + name, "varchar(255)", parentParamDesc + "-" + paramDesc));
                        continue;
                    }
                    System.out.println("内层发现未知类型：" + type + "  属性名：" + name);
                }
                continue;
            }

            System.out.println("外层发现未知类型：" + paramType + " 属性名：" + jsonObject1.get("name"));
        }

        //全不处理完成之后，会发现 enNameTypeCommentArrayList 里面有很多重复的字段，需要去重
        HashSet<String> enNameSet = new HashSet<>();
        ArrayList<EnName_Type_Comment> 去重之后的字段 = new ArrayList<>();
        for (EnName_Type_Comment enNameTypeComment : enNameTypeCommentArrayList) {
            if (enNameSet.contains(enNameTypeComment.getEnName())) {
                continue;
            }
            enNameSet.add(enNameTypeComment.getEnName());
            去重之后的字段.add(enNameTypeComment);
        }
        enNameTypeCommentArrayList = 去重之后的字段;

        StringBuffer createTableSql = new StringBuffer();
        //todo 记住，生成完sql语句之后，要改一下表名和comment 还要执行一下，基本上都是需要去调整 varchar(255)的长度
        createTableSql.append("记得修改表名和comment \n");
        createTableSql.append("create table test_table (");
        createTableSql.append("bai_shu_id bigint primary key auto_increment comment '百数云id',");
        createTableSql.append("bai_shu_create_time datetime default current_timestamp comment '百数云创建时间',");
        for (EnName_Type_Comment enNameTypeComment : enNameTypeCommentArrayList) {
            createTableSql.append(enNameTypeComment.getEnName() + " " + enNameTypeComment.getType() + " null comment '" + enNameTypeComment.getComment() + "',");
        }
        createTableSql.deleteCharAt(createTableSql.length() - 1);
        createTableSql.append(") comment '用友bip表';");
        //将 createTableSql.toString() 里面的 ！ 替换成 _
        System.out.println(createTableSql.toString().replace("!", "_"));



    }

    private static void checkHowManyType(JSONArray jsonArray) {
        HashSet<String> objects = new HashSet<>();
        for (Object o : jsonArray) {
            JSONObject jsonObject = (JSONObject) o;
            String paramType = (String) jsonObject.get("paramType");
            objects.add(paramType);
        }
        System.out.println(objects);
    }
}

class EnName_Type_Comment {
    private String enName;
    private String type;
    private String comment;

    public EnName_Type_Comment(String enName, String type, String comment) {
        this.enName = enName;
        this.type = type;
        this.comment = comment;
    }

    public String getEnName() {
        return enName;
    }

    public void setEnName(String enName) {
        this.enName = enName;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }
}